﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace PmSoft.Web.Abstractions.Filters;

/// <summary>
/// 全局 API 响应过滤器，用于统一包装 API 响应格式。
/// </summary>
public class GlobalApiResponseFilter : IActionFilter
{
	/// <summary>
	/// 在 Action 执行之前调用。
	/// </summary>
	/// <param name="context">Action 执行上下文。</param>
	public void OnActionExecuting(ActionExecutingContext context)
	{
		// 在 Action 执行之前调用（无需处理）
	}

	/// <summary>
	/// 在 Action 执行之后调用，统一包装响应格式。
	/// </summary>
	/// <param name="context">Action 执行上下文。</param>
	public void OnActionExecuted(ActionExecutedContext context)
	{
		if (context.Result is ObjectResult objectResult)
		{
			// 处理 ObjectResult
			context.Result = WrapObjectResult(objectResult);
		}
		else if (context.Result is EmptyResult)
		{
			// 处理 EmptyResult
			context.Result = WrapEmptyResult();
		}
		else if (context.Result is BadRequestObjectResult badRequestObjectResult)
		{
			// 处理 BadRequestObjectResult
			context.Result = WrapBadRequestResult(badRequestObjectResult);
		}
		// 可以根据需要处理其他类型的 Result
	}

	/// <summary>
	/// 包装 ObjectResult 为 ApiResult 格式。
	/// </summary>
	/// <param name="objectResult">原始的 ObjectResult。</param>
	/// <returns>包装后的 ObjectResult。</returns>
	private ObjectResult WrapObjectResult(ObjectResult objectResult)
	{
		object response;

		//if (objectResult.Value is ApiResult || (objectResult.Value?.GetType().IsGenericType == true
		//	&& objectResult.Value.GetType().GetGenericTypeDefinition() == typeof(ApiResult<>)))
		if(objectResult.Value is IApiResult)
		{
			// 如果已经是 ApiResult 类型，直接使用
			response = objectResult.Value;
		}
		else
		{
			// 否则包装为 ApiResult
			response = ApiResult.Ok(objectResult.Value);
		}

		return new ObjectResult(response)
		{
			StatusCode = objectResult.StatusCode
		};
	}

	/// <summary>
	/// 包装 EmptyResult 为 ApiResult 格式。
	/// </summary>
	/// <returns>包装后的 ObjectResult。</returns>
	private ObjectResult WrapEmptyResult()
	{
		var response = ApiResult.Ok("OK");
		return new ObjectResult(response)
		{
			StatusCode = StatusCodes.Status200OK
		};
	}

	/// <summary>
	/// 包装 BadRequestObjectResult 为 ApiResult 格式。
	/// </summary>
	/// <param name="badRequestObjectResult">原始的 BadRequestObjectResult。</param>
	/// <returns>包装后的 ObjectResult。</returns>
	private ObjectResult WrapBadRequestResult(BadRequestObjectResult badRequestObjectResult)
	{
		var response = ApiResult.Error(badRequestObjectResult.Value);
		return new ObjectResult(response)
		{
			StatusCode = badRequestObjectResult.StatusCode
		};
	}
}